/*
 * BackoffLock.java
 *
 * Created on January 20, 2006, 11:02 PM
 *
 * From "Multiprocessor Synchronization and Concurrent Data Structures",
 * by Maurice Herlihy and Nir Shavit.
 *
 * This work is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
 * http://i.creativecommons.org/l/by-sa/3.0/us/88x31.png
 */

package mpp;

/**
 * Exponential backoff lock
 * @author Maurice Herlihy
 */
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
public class BackoffLock implements Lock {
  private AtomicBoolean state = new AtomicBoolean(false);  
  private static final int MIN_DELAY = 32;
  private static final int MAX_DELAY = 1024;
  
  
  public void lock() {
    Backoff backoff = new Backoff(MIN_DELAY, MAX_DELAY);
    
    while (true) {
      while (state.get()) {}	// spin
      if (!state.getAndSet(true)) { // try to acquire lock
        return;
      } else {			// backoff on failure
        try {
          backoff.backoff();
        } catch (InterruptedException ex) {
        }
      }
    }
  }  
  
  public void unlock() {
    state.set(false);
  }
  
  
  // Any class implementing Lock must provide these methods
  public Condition newCondition() {
    throw new java.lang.UnsupportedOperationException();
  }
  public boolean tryLock(long time,
      TimeUnit unit)
      throws InterruptedException {
    throw new java.lang.UnsupportedOperationException();
  }
  public boolean tryLock() {
    throw new java.lang.UnsupportedOperationException();
  }
  public void lockInterruptibly() throws InterruptedException {
    throw new java.lang.UnsupportedOperationException();
  }
}
